﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WowRaidListTracker.DAL;
using System.Data;

namespace WowRaidListTracker.core.Application
{
    public class ListManager : Manager
    {
        public static Dictionary<int, List<RaidMemberList>> RaidMemberLists =
            new Dictionary<int,List<RaidMemberList>>();
        public static Dictionary<int, int> MaxRankAllLists = new Dictionary<int, int>();

        public delegate void MemberListUpdateEventHandler(object sender, EventArgs e);

        private event MemberListUpdateEventHandler memberListUpdated;
        public event MemberListUpdateEventHandler MemberListUpdated
        {
            add
            {
                memberListUpdated += value;
            }
            remove
            {
                memberListUpdated -= value;
            }
        }

        private int currentTypeId;

        private List<RaidMemberList> mRaidMemberList;
        public List<RaidMemberList> RaidMemberList
        {
            get { return mRaidMemberList; }
        }

        public ListManager()
            : base()
        {
            //LoadLists();
            LoadMaxRanks();
        }

        public void LoadLists()
        {
            object dt = dal.Execute(
                CRUDReader.Crud.get("RaidMemberLists", CRUDReader.QUDType.Select),
                SQLiteQueryType.STANDARDQUERY
            );
            RaidMemberLists = new Dictionary<int, List<RaidMemberList>>();
            if (typeof(DataTable) == dt.GetType())
            {
                DataTable data = (dt as DataTable);

                foreach (DataRow dr in data.Rows)
                {
                    RaidMemberList rl = new RaidMemberList(dr);
                    if (RaidMemberLists.ContainsKey(rl.TypeId))
                    {
                        RaidMemberLists[rl.TypeId].Add(rl);
                    }
                    else
                    {
                        RaidMemberLists.Add(rl.TypeId, new List<RaidMemberList>());
                        RaidMemberLists[rl.TypeId].Add(rl);
                    }
                }
            }
        }

        public void ShiftRanks(RaidMemberList rml)
        {
            // we need to build a list of ranks
            int maxRank = MaxRankAllLists[currentTypeId];
            if (maxRank == rml.CurrentRank)
            {
                return; // if the rank matches the max rank then we don't need to do anything
            }

            List<RaidMemberList> filteredList = RaidMemberList.FindAll(r => r.CurrentRank > rml.CurrentRank);
            filteredList.Sort();
            if (filteredList.Count > 0)
            {
                // there are more items in the list we need to update many ranks
                List<RaidMemberList> notPresentMemberList = RaidMemberLists[currentTypeId].FindAll(r => r.Member.IsPresent == false);
                Dictionary<int, bool> skipRanks = new Dictionary<int, bool>();
                // fill the skipped ranks
                foreach (RaidMemberList l in notPresentMemberList)
                {
                    skipRanks.Add(l.CurrentRank, true);
                }

                // loop through the filtered list and change ranks on the members in the list
                // give the passed member the max rank
                foreach (RaidMemberList l in filteredList)
                {
                    l.CurrentRank--;
                    while (skipRanks.ContainsKey(l.CurrentRank))
                        l.CurrentRank--;
                    l.UpdateRank();
                }
                rml.CurrentRank = MaxRankAllLists[currentTypeId];
                rml.UpdateRank();
            }
            RaidMemberList.Sort();
        }

        public void SetCurrentList(int typeId)
        {
            if (RaidMemberLists.ContainsKey(typeId))
                mRaidMemberList = RaidMemberLists[typeId].FindAll(r => r.Member.IsPresent == true);
            else
                mRaidMemberList = new List<RaidMemberList>();
            currentTypeId = typeId;
        }

        public void AddMemberToList(int typeId, RaidMember r)
        {
            RaidMemberList rl = new RaidMemberList()
            {
                MemberId = r.Id,
                TypeId = typeId
            };

            if (!MaxRankAllLists.ContainsKey(typeId))
                MaxRankAllLists.Add(typeId, 0);

            rl.CurrentRank = ++MaxRankAllLists[typeId];

            rl.AddItem();

            if (!RaidMemberLists.ContainsKey(typeId))
                RaidMemberLists.Add(typeId, new List<RaidMemberList>());
            RaidMemberLists[typeId].Add(rl);
            RaidMemberLists[typeId].Sort();

            OnListUpdated(rl);
        }

        public void LoadMaxRanks()
        {
            DataTable dt = (DataTable)dal.Execute(
                CRUDReader.Crud.get("RaidMemberListMaxRank", CRUDReader.QUDType.Select),
                SQLiteQueryType.STANDARDQUERY
            );
            MaxRankAllLists = new Dictionary<int, int>();
            foreach (DataRow dr in dt.Rows)
            {
                MaxRankAllLists.Add(
                    Convert.ToInt32(dr["TypeId"]),
                    Convert.ToInt32(dr["MaxRank"])
                );
            }
        }

        private void OnListUpdated(RaidMemberList rml)
        {
            if (memberListUpdated != null)
            {
                memberListUpdated(rml, new EventArgs());
            }
        }
    }
}
